using System;
using System.Collections.Generic;
using System.Text;

namespace WOWEquipOptimizer.Druid
{
    class Cat : Character
    {
        public Cat()
            : base()
        {
            m_Base = new List<Attribute>();
            m_Base.Add(new Attribute(AttributeName.Health, 3500));
            m_Base.Add(new Attribute(AttributeName.Stamina, 97));
            m_Base.Add(new Attribute(AttributeName.Strength, 83));
            m_Base.Add(new Attribute(AttributeName.AttackPower, 146));
            m_Base.Add(new Attribute(AttributeName.CritRating, 0.97f * CritRating));
            m_Base.Add(new Attribute(AttributeName.Agility, 66));
            // talents below
            m_Base.Add(new Attribute(AttributeName.CritRating, 6 * CritRating));
            m_Base.Add(new Attribute(AttributeName.AttackPower, 105));
            m_Base.Add(new Attribute(AttributeName.AttackPower, 140));
            foreach (Attribute attr in m_Base)
            {
                handleAttribute(attr);
            }
            Buff bom = new Buff("Blessing of Might", new List<Attribute>());
            bom.Attributes.Add(new Attribute(AttributeName.AttackPower, 220));
            Buffs.Add(bom);
            Buff relassault = new Buff("Flask of Relentless Assault", new List<Attribute>());
            relassault.Attributes.Add(new Attribute(AttributeName.AttackPower, 120));
            Buffs.Add(relassault);
            Buff majagi = new Buff("Elixir of Major Agility", new List<Attribute>());
            majagi.Attributes.Add(new Attribute(AttributeName.Agility, 35));
            majagi.Attributes.Add(new Attribute(AttributeName.CritRating, 20));
            majagi.Enabled = false;
            Buffs.Add(majagi);
            Buff battleshout = new Buff("Battleshout", new List<Attribute>());
            battleshout.Attributes.Add(new Attribute(AttributeName.AttackPower, 385));
            Buffs.Add(battleshout);
            Buff lotp = new Buff("Leader of the pack", new List<Attribute>());
            lotp.Attributes.Add(new Attribute(AttributeName.CritRating, (int)(5 * CritRating)));
            Buffs.Add(lotp);
            Buff roastcleft = new Buff("Roasted Clefthoof", new List<Attribute>());
            roastcleft.Attributes.Add(new Attribute(AttributeName.Strength, 20));
            roastcleft.Attributes.Add(new Attribute(AttributeName.Spirit, 20));
            Buffs.Add(roastcleft);
            Buff mudfish = new Buff("Grilled Mudfish", new List<Attribute>());
            mudfish.Attributes.Add(new Attribute(AttributeName.Agility, 20));
            mudfish.Attributes.Add(new Attribute(AttributeName.Spirit, 20));
            mudfish.Enabled = false;
            Buffs.Add(mudfish);
            Buff soe = new Buff("Strength of Earth", new List<Attribute>());
            soe.Attributes.Add(new Attribute(AttributeName.Strength, 88 * 1.15f));
            Buffs.Add(soe);
            Buff goa = new Buff("Grace of Air", new List<Attribute>());
            goa.Attributes.Add(new Attribute(AttributeName.Strength, 77 * 1.15f));
            goa.Enabled = true;
            Buffs.Add(goa);
        }
        //Crit,Hit, AP,health
        public override void handleAttribute(Attribute attr)
        {
            switch (attr.Type)
            {
                case AttributeName.Agility:
                    m_Equip[AttributeName.CritRating] += 1.03f * (attr.Value * (HasBlessingOfKings ? 1.1f : 1.0f) / 25f) * CritRating;
                    m_Equip[AttributeName.AttackPower] += 1.03f * attr.Value * (HasBlessingOfKings ? 1.1f : 1.0f);
                    break;
                case AttributeName.CritMeleeRating:
                case AttributeName.CritRating:
                    m_Equip[AttributeName.CritRating] += attr.Value;
                    break;
                case AttributeName.HitMeleeRating:
                case AttributeName.HitRating:
                    m_Equip[AttributeName.HitRating] += attr.Value;
                    break;
                case AttributeName.FeralAP:
                case AttributeName.AttackPower:
                    m_Equip[AttributeName.AttackPower] += attr.Value;
                    break;
                case AttributeName.Strength:
                    m_Equip[AttributeName.AttackPower] += 1.03f * attr.Value * 2 * (HasBlessingOfKings ? 1.1f : 1.0f) * 1.2f;
                    break;
                case AttributeName.Stamina:
                    m_Equip[AttributeName.Health] += 1.03f * attr.Value * 10 * (HasBlessingOfKings ? 1.1f : 1.0f);
                    break;
                default:
                    base.handleAttribute(attr);
                    break;
            }
        }
        //Crit,Hit, AP,health
        public override float evaluateTF()
        {
            
            //mangle, shred up to 5cp, rip
            float crit = m_Equip[AttributeName.CritRating] / CritRating;
            float hit = m_Equip[AttributeName.HitRating] / HitRating;
            float wdps = 54.8f;
            hit = (float)Math.Min(100 - 5 - 3.0f - 0.6f + hit, 100);
            float dodge = 5.6f; // 5.6% dodge chance of the boss
            float ap = m_Equip[AttributeName.AttackPower];
            float attacktable = (1 / 100f) * (hit - dodge + (crit + 10f));
            float shredcount = (5 - (1 + crit / 100)) / (1 + crit / 100);
            float rotenergy = 40f + 42f * shredcount + 30f;
            float avgenergy = rotenergy / (2 + shredcount);
            float rottime = rotenergy / 10f;
            rottime -= ((rottime / 60f) * 2f * (avgenergy / 10f)); // crude includes omen of clarity, two omen procs, 0.5 procs per rotation, so basically around 2s less rotation time
            float shredadd = 405;
            if (this.SpecialValues.Contains("11865252"))
            {
                shredadd += 88;
            }
            float whitedmg = wdps + ap / 14f;
            float whitedps = attacktable * whitedmg;
            float mangledmg = 1.2f * attacktable * (1.6f * whitedmg + 264);
            float shreddmg = 1.3f * attacktable * (2.25f * whitedmg + shredadd);
            float ripdmg = 1.3f * (1554 + 0.24f * ap);
            float rotdmg = Character.Armor * mangledmg + shredcount * Character.Armor * shreddmg + ripdmg;
            float finaldps = 1.1f * (rotdmg / rottime + Character.Armor*whitedps); //naturalist dmg *1.1f
            return CondFactor * finaldps;
        }
        public override List<Item> filterEquip(List<Item> input)
        {
            input = base.filterEquip(input);
            List<Item> retval = new List<Item>();
            foreach (Item item in input)
            {
                if ((item.AllowableClasses & CharacterClass.Druid) == 0) continue;
                if (item.GetType() == typeof(Weapon))
                {
                    Weapon weapon = (Weapon)item;
                    if (weapon.WeaponSlot != WeaponSlot.Ranged)
                    {
                        if (!weapon.TwoHand) continue;
                        if (!(weapon.Type == WeaponType.Staff || weapon.Type == WeaponType.Mace)) continue;
                    }
                    else if (weapon.WeaponSlot == WeaponSlot.Ranged)
                    {
                        if (weapon.Type != WeaponType.Idol) continue;
                    }
                }
                else if (item.GetType() == typeof(Armor))
                {
                    Armor armor = (Armor)item;
                    if ((armor.Type & ArmorProficiency.Leather) == 0) continue;
                    if (armor.Slot == ArmorSlot.OffHand) continue;
                }
                if (SetBlacklist.Contains(item.Set.Name)) continue;
                if (ItemBlacklist.Contains(item.Name)) continue;
                bool bad = false;
                foreach (Attribute attr in item.Attributes)
                {
                    switch (attr.Type)
                    {
                        case AttributeName.SpellDamage:
                        case AttributeName.HitSpellRating:
                        case AttributeName.CritSpellRating:
                        case AttributeName.MP5:
                        case AttributeName.Healing:
                            {
                                bad = true;
                                break;
                            }
                        default:
                            break;
                    }
                }
                if (!bad)
                {
                    retval.Add(item);
                }
            }
            return handleWhiteList(retval);
        }
        public override bool evaluateBuild(int[] build)
        {
            if (build[1] >= 41 && build[2] >= 11)
            {
                return true;
            }
            else return false;
        }
        public override string[] getAttributes()
        {
            return new string[] { "CritRating", "HitRating", "Attackpower", "Health" };
        }
        public override string targetValue()
        {
            return "DPS";
        }
    }
}
